#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Created on 2022-04-06 14:11:06
@author: DengLibin 榆霖
@description: 简单神经网络
'''
import numpy as np



def sigmoid(x, deriv = False):
    """
    sigmoid(x) = 1 / (1 + e**(-x))

    Args:
        x (_type_): _description_
        deriv (bool, optional): _description_. Defaults to False.

    Returns:
        _type_: _description_
    """
    if deriv:
        return x*(1-x)
    return 1/(1+np.exp(-x))

def create_data():
    # 3行4列
    x = np.array([[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1],[0, 0, 1]])
    label = np.array([[0],  [1],       [1],       [0],       [0]])
    return x, label

def run():
    np.random.seed(1)
    x, label = create_data()
    
    feature_num = x.shape[1]
    # 第一层(矩阵: 行数就是data的列数，不然不能相乘， 列数任意，神经元数)
    w0 = 2 * np.random.random((feature_num, 4)) - 1
    # 第二层（矩阵，行数就是w0的列数，不然不能相乘，列数和label的列数一样只有一列）
    w1 = 2 * np.random.random((w0.shape[1], 1)) - 1
    print("--------------------------------w0------------------------------------------")
    print(w0)
    print("--------------------------------w1------------------------------------------")
    print(w1)
    
    for i in range(60000):
        l0 = x
        l1 = sigmoid(np.dot(l0, w0))
        l2 = sigmoid(np.dot(l1, w1))
        # 误差
        l2_error = label - l2
        if i % 10000 == 0:
            # mean函数 求均值
            print("Error:", str(np.mean(np.abs(l2_error))))
        l2_delta = l2_error * sigmoid(l2, deriv=True)
        
        l1_error = l2_delta.dot(w1.T)
        l1_delta = l1_error * sigmoid(l1, deriv = True)
        
        w1 += l1.T.dot(l2_delta)
        w0 += l0.T.dot(l1_delta)

if __name__ == '__main__':
   run()
